/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.tbp.persitence.dao.impl;

import br.com.tbp.exception.PersistenciaException;
import br.com.tbp.model.domain.Empresa;
import br.com.tbp.persitence.FabricaDePersistencia;
import br.com.tbp.persitence.GerenciadorDeConexao;
import br.com.tbp.persitence.GerenciadorDeQuery;
import br.com.tbp.persitence.dao.EmpresaDao;
import br.com.tbp.persitence.dao.EnderecoDao;
import br.com.tbp.utils.DateUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Diego Freire
 */
public class EmpresaDaoImpl implements EmpresaDao {

    private Connection conn = null;
    private PreparedStatement pr = null;
    private ResultSet rs = null;

    public void adicionar(Empresa e) throws PersistenciaException {
        if (e == null) {
            throw new PersistenciaException("Não foi informado a empresa a cadastrar.");
        }

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("empresa.insert"),
                    Statement.RETURN_GENERATED_KEYS);
            pr.setString(1, e.getRazaoSocial());
            pr.setString(2, e.getNomeFantasia());
            pr.setString(3, e.getCnpj());
            pr.setString(4, e.getInscricao());
            pr.setString(5, e.getTelefone());
            pr.setString(6, e.getEmail());
            pr.setString(7, e.getRepresentante());
            pr.setString(8, e.getContato());
            pr.setBoolean(9, e.isAtiva());
            pr.setLong(10, e.getEndereco() != null ? e.getEndereco().getId() : 0);
            pr.setString(11, e.getEndereco() != null ? e.getEndereco().getComplemento() : null);
            pr.setString(12, e.getObservacoes());

            pr.executeUpdate();

            rs = pr.getGeneratedKeys();
            rs.next();
            long id = rs.getLong(1);
            e.setId(id);

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível cadastrar a empresa.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
    }

    public void atualizar(Empresa e) throws PersistenciaException {
        if (e == null) {
            throw new PersistenciaException("Não foi informado a empresa a atualizar.");
        }

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("empresa.update"));
            pr.setString(1, e.getRazaoSocial());
            pr.setString(2, e.getNomeFantasia());
            pr.setString(3, e.getCnpj());
            pr.setString(4, e.getInscricao());
            pr.setString(5, e.getTelefone());
            pr.setString(6, e.getEmail());
            pr.setString(7, e.getRepresentante());
            pr.setString(8, e.getContato());
            pr.setBoolean(9, e.isAtiva());
            pr.setLong(10, e.getEndereco() != null ? e.getEndereco().getId() : 0);
            pr.setString(11, e.getEndereco() != null ? e.getEndereco().getComplemento() : null);
            pr.setString(12, e.getObservacoes());
            pr.setLong(13, e.getId());
            pr.executeUpdate();

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível atualizar a empresa.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr);
        }
    }

    public void remover(Empresa e) throws PersistenciaException {
        if (e == null) {
            throw new PersistenciaException("Não foi informado a empresa a remover.");
        }

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("empresa.delete"));
            pr.setLong(1, e.getId());
            pr.executeUpdate();

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível remover a empresa.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr);
        }
    }

    private Empresa criarEmpresa(ResultSet rs, EnderecoDao endereco_dao) throws PersistenciaException {
        Empresa e = null;
        try {
            e = new Empresa(rs.getLong("id_empresa"));
            e.setDataDoCadastro(DateUtils.dataBancoDeDadosParaDataObjeto(
                    rs.getDate("data_cadastro")));
            e.setRazaoSocial(rs.getString("razao_social"));
            e.setNomeFantasia(rs.getString("nome_fantasia"));
            e.setCnpj(rs.getString("cnpj"));
            e.setInscricao(rs.getString("inscricao_estadual"));
            e.setTelefone(rs.getString("telefone"));
            e.setEmail(rs.getString("email"));
            e.setRepresentante(rs.getString("representante"));
            e.setContato(rs.getString("contato"));
            e.setAtiva(rs.getBoolean("ativa"));
            e.setEndereco(endereco_dao.pesquisar(rs.getLong("id_endereco")));
            if (e.getEndereco() != null) {
                e.getEndereco().setComplemento(rs.getString("complemento"));
            }
            e.setObservacoes(rs.getString("observacoes"));
        } catch (SQLException sqlex) {
            StringBuilder msg = new StringBuilder("Não foi possível obter os dados da empresa.");
            msg.append("\nMotivo: ").append(sqlex.getMessage());
            throw new PersistenciaException(msg.toString());
        }
        return e;
    }

    public List<Empresa> pesquisar() throws PersistenciaException {
        List<Empresa> lista = new ArrayList<Empresa>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("empresa.select"));
            rs = pr.executeQuery();

            if (rs != null) {
                EnderecoDao endereco_dao = FabricaDePersistencia.createEnderecoDao();
                while (rs.next()) {
                    Empresa c = this.criarEmpresa(rs, endereco_dao);
                    lista.add(c);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar as empresas.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }

        return lista;
    }

    public List<Empresa> pesquisarPorNomeFantasia(String str) throws PersistenciaException {
        List<Empresa> lista = new ArrayList<Empresa>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("empresa.select.fantasia"));
            pr.setString(1, str + "%");
            rs = pr.executeQuery();

            if (rs != null) {
                EnderecoDao endereco_dao = FabricaDePersistencia.createEnderecoDao();
                while (rs.next()) {
                    Empresa c = this.criarEmpresa(rs, endereco_dao);
                    lista.add(c);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar as empresas.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }

        return lista;
    }

    public List<Empresa> pesquisarPorRazaoSocial(String str) throws PersistenciaException {
        List<Empresa> lista = new ArrayList<Empresa>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("empresa.select.razao"));
            pr.setString(1, str + "%");
            rs = pr.executeQuery();

            if (rs != null) {
                EnderecoDao endereco_dao = FabricaDePersistencia.createEnderecoDao();
                while (rs.next()) {
                    Empresa c = this.criarEmpresa(rs, endereco_dao);
                    lista.add(c);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar as empresas.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }

        return lista;
    }

    public List<Empresa> pesquisarPorCnpj(String str) throws PersistenciaException {
        List<Empresa> lista = new ArrayList<Empresa>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("empresa.select.cnpj"));
            pr.setString(1, str);
            rs = pr.executeQuery();

            if (rs != null) {
                EnderecoDao endereco_dao = FabricaDePersistencia.createEnderecoDao();
                while (rs.next()) {
                    Empresa c = this.criarEmpresa(rs, endereco_dao);
                    lista.add(c);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar as empresas.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }

        return lista;
    }

    public Empresa pesquisarPorId(long id) throws PersistenciaException {
        Empresa e = null;
        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("empresa.select.id"));
            pr.setLong(1, id);
            rs = pr.executeQuery();

            if (rs != null) {
                EnderecoDao endereco_dao = FabricaDePersistencia.createEnderecoDao();
                if (rs.first()) {
                    e = this.criarEmpresa(rs, endereco_dao);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar as empresas.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
        return e;
    }

    public List<Empresa> pesquisar(int limit1, int limit2) throws PersistenciaException {
        List<Empresa> lista = new ArrayList<Empresa>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("empresa.select.limit"));
            pr.setInt(1, limit1);
            pr.setInt(2, limit2);
            rs = pr.executeQuery();

            if (rs != null) {
                EnderecoDao endereco_dao = FabricaDePersistencia.createEnderecoDao();
                while (rs.next()) {
                    Empresa c = this.criarEmpresa(rs, endereco_dao);
                    lista.add(c);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar as empresas.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }

        return lista;
    }

    public long verificarDuplicidade(String cnpj) throws PersistenciaException {

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("empresa.verifica.cnpj"));
            pr.setString(1, cnpj);
            rs = pr.executeQuery();

            if (rs != null) {
                if (rs.first()) {
                    long empresaId = rs.getLong("id_empresa");
                    return empresaId;
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível verificar a duplicidade de empresas.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }

        return 0;
    }
}
